
#include "../myTime.hpp"
#include "../rand.hpp"
#include <cassert>
#include <forward_list>
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
using namespace std;

int main() {
  const int num = 2000000;
  unordered_map<int, int> mmp(num * 2);
  unordered_map<int, int> mmp2(num);

  map<int, int> mp;

  vector<int> vec1(num);
  cout << mmp.size() << endl;
  cout << mmp.max_size() << endl;
  cout << mmp.bucket_count() << endl;
  cout << mmp.max_bucket_count() << endl;

  // for (int i = 0; i < num * 2; i += 2)
  //   mmp[i] = i;
  // cout << mmp.size() << endl;
  // cout << mmp.bucket_count() << endl;

  IntRandom rd(0, num - 1);

  vector<int> rand_vec(num);
  for (int i = 0; i < num; ++i)
    rand_vec[i] = rd(0);

  MyTimer(0, "vec1 []");
  for (int i = 0; i < num; ++i)
    vec1[rand_vec[i]] = rand_vec[i];
  MyTimer(1, "vec1 []");

  MyTimer(0, "unordered_map []");
  for (int i = 0; i < num; ++i)
    mmp[rand_vec[i]] = rand_vec[i];
  MyTimer(1, "unordered_map []");

  MyTimer(0, "map []");
  for (int i = 0; i < num; ++i)
    mp[rand_vec[i]] = rand_vec[i];
  MyTimer(1, "map []");

  cout << mmp.bucket_count() << endl;
  cout << mmp.max_bucket_count() << endl;

  MyTimer(0, "unordered_map2 []");
  for (int i = 0; i < num; ++i)
    mmp2.insert({rand_vec[i], rand_vec[i]});
  MyTimer(1, "unordered_ma2 []");

  MyTimer(0, "unordered_map kv []");
  int id{0};
  for (auto &kv : mmp)
    kv.second = id++;
  MyTimer(1, "unordered_map kv []");

  MyTimer(0, "unordered_map erase []");
  for (int i = 0; i < num / 2; ++i)
    mmp.erase(rand_vec[i]);
  MyTimer(1, "unordered_map erase []");

  int size = mmp.size();
  cout << "size=" << size << endl;

  MyTimer(0, "unordered_map rehash []");
  mmp.rehash(size);
  MyTimer(1, "unordered_map rehash []");

  cout << mmp.bucket_count() << endl;
  cout << mmp.max_bucket_count() << endl;

  return 0;
}